package com.afeng.db.mysql.config;

import com.alibaba.druid.pool.DruidDataSource;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

/**
 * 
 * @Title       : DemoDatabaseConfig
 * @Description : demo模块数据源配置
 * @Date        : 2017年11月15日
 * @author      : afeng
 */
@Configuration
@ConfigurationProperties(prefix = "")
@PropertySource("classpath:mysql.properties")
@MapperScan(basePackages = "com.afeng.db.mysql.dao", sqlSessionFactoryRef = "DemoSqlSessionFactory")
public class DemoDatabaseConfig {

    @Value(value = "${demo.datasource.url}")
    private String url;
    @Value(value = "${demo.datasource.username}")
    private String username;
    @Value(value = "${demo.datasource.password}")
    private String password;
    @Value(value = "${demo.datasource.driver}")
    private String driverName;
    // 配置初始化大小、最小、最大
    @Value(value = "${druid.initialSize:5}")
    private int initialSize;
    @Value(value = "${druid.minIdle:5}")
    private int minIdle;
    @Value(value = "${druid.maxActive:200}")
    private int maxActive;
    // 配置获取连接等待超时的时间
    @Value(value = "${druid.maxWait:20000}")
    private long maxWait;
    // 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
    @Value(value = "${druid.timeBetweenEvictionRunsMillis:60000}")
    private long timeBetweenEvictionRunsMillis;
    @Value(value = "${druid.validationQuery:select 'x'}")
    private String validationQuery;
    @Value(value = "${druid.testWhileIdle:true}")
    private boolean testWhileIdle;
    @Value(value = "${druid.testOnBorrow:false}")
    private boolean testOnBorrow;
    @Value(value = "${druid.testOnReturn:false}")
    private boolean testOnReturn;
    @Value(value = "${druid.removeAbandoned:true}")
    private boolean removeAbandoned;
    @Value(value = "${druid.removeAbandonedTimeout:180}")
    private int removeAbandonedTimeout;
    @Value(value = "${druid.logAbandoned:true}")
    private boolean logAbandoned;

    @Bean(name = "demoDataSource")
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverName);
        dataSource.setInitialSize(initialSize);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxActive(maxActive);
        dataSource.setMaxWait(maxWait);
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        dataSource.setValidationQuery(validationQuery);
        dataSource.setTestWhileIdle(testWhileIdle);
        dataSource.setTestOnBorrow(testOnBorrow);
        dataSource.setTestOnReturn(testOnReturn);
        return dataSource;
    }

    @Bean(name = "DemoSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("demoDataSource") DataSource demoDataSource)
            throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(demoDataSource);
        sessionFactory.setConfigLocation(new ClassPathResource("/mybatis-config.xml"));
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setMapperLocations(resolver.getResources("classpath:/sqlmap/demo/*Mapper.xml"));
        return sessionFactory.getObject();
    }

    @Bean(name = "demoTransactionManager")
    public DataSourceTransactionManager demoTransactionManager(@Qualifier("demoDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

}
